package chapter16.Practic;
/*
    RationaNumber.java    Java Foundations   Program5.11
  
    Represents ine ratuinal number with a numeratir and denominator.
*/

public class RationalNumber
{
    private int numerator, denominator;
   
    //-----------------------------------------------------------------
    // Constructor: Sets up the rational number by ensuring a nonzero
    // denominator and making only the numerator signed.
    //-----------------------------------------------------------------
    public RationalNumber(int numer, int denom)
    {
       if(denom == 0 )
          denom = 1;
    
       // Mak the numerator "store" the sign
       if (denom < 0)
       {
          numer = numer * -1;
          denom = denom * -1;
       }
  
       numerator = numer;
       denominator = denom;

       reduce();
    }
 
    // Returns the numerator of this rational number.
    public int getNumerator()
    {
        return numerator;
    }
   
    // Returns the denominator of this rational number.
    public int getDenominator()
    {
        return denominator;
    }
  
    // Returns the reciprocl of this rational number.
    public RationalNumber reciprocal()
    {
        return new RationalNumber (denominator, numerator);
    }

    //-----------------------------------------------------------
    // Adds this rational number to the one passed as a parameter.
    // A common denominator is found by multiplying the individual
    // denominators.
    //------------------------------------------------------------
    public RationalNumber add(RationalNumber op2)
    {
       int commonDenominator = denominator * op2.getDenominator();
       int numerator1 = numerator * op2.getDenominator();
       int numerator2 = op2.getNumerator() * denominator;
       int sum = numerator1 + numerator2;

       return new RationalNumber (sum, commonDenominator);
    }

    //------------------------------------------------------------
    // Subtracts the rational numer passed as a parameter from this 
    // ratioal number.
    //------------------------------------------------------------
    public RationalNumber subtract(RationalNumber op2)
    {
        int commonDenominator = denominator * op2.getDenominator();
        int numerator1 = numerator * op2.getDenominator();
        int numerator2 = op2.getNumerator() * denominator;
        int difference = numerator1 - numerator2;

        return new RationalNumber(difference,commonDenominator);
    }
 
    //--------------------------------------------------------------
    // Multiplies this rational number by the one passed as a
    // parameter.
    //-------------------------------------------------------------
    public RationalNumber multiply (RationalNumber op2)
    {
        int numer = numerator * op2.getNumerator();
        int denom = denominator * op2.getDenominator();
  
        return new RationalNumber (numer, denom);
    }
  
   //--------------------------------------------------------------
   // Divides this rational number by the one passed as a parameter
   // bymltiplying by the recuprocal of the second rational.
   //--------------------------------------------------------------
   public RationalNumber divide (RationalNumber op2)
   {
       return multiply (op2.reciprocal());
   }

   //---------------------------------------------------------------
   // Determines if this ratuonal number is equal to the one passed 
   // as a parameter. Assumes they are both reduced.
   //---------------------------------------------------------------
   public boolean isLike (RationalNumber op2)
   {
       return (numerator == op2.getNumerator() &&
               denominator == op2.getDenominator());
   }

   // Returans this rational number as a string.
   public String toString()
   {
      String result;
   
      if (numerator == 0)
         result = "0";
      else
         if (denominator == 1)
             result = numerator + "";
         else 
             result = numerator + "/" + denominator;
      
       return result;
   }
 
   //---------------------------------------------------------------
   // Reduces this rational number by dividing both the numerator
   // and the deominator by their greatest common divisor.
   //---------------------------------------------------------------
   private void reduce()
   {
       if (numerator != 0)
       { 
          int common = gcd (Math.abs(numerator), denominator);

          numerator = numerator / common;
          denominator = denominator / common;
       }
   }

   //-------------------------------------------------------------
   // Computes and returns the greatest common divisor of the two
   // positive [arameters. Uses Euclid's algorithm.
   //------------------------------------------------------------
   private int gcd (int num1, int num2)
   {
        while (num1 != num2)
           if (num1 > num2)
               num1 = num1 - num2;
           else 
               num2 = num2 - num1;

        return num1;
   }
}

